package br.unifor.mia.graph;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Transaction;

import br.unifor.mia.graph.setorcensitario.CrimeMetrics;
import br.unifor.mia.graph.setorcensitario.Link;
import br.unifor.mia.graph.setorcensitario.Metrics;
import br.unifor.mia.graph.setorcensitario.Node;
import br.unifor.mia.graph.setorcensitario.SectorGraphFactory;
import br.unifor.mia.graph.util.CalcUtil;
import br.unifor.mia.graph.util.DB;

public class Main {

	@SuppressWarnings("unchecked")
	private static List<Link> createUserGraph(List<Link> allLinks) {

		List<Link> newLinks = new ArrayList<Link>();

		Transaction trans = DB.getSession().beginTransaction();

		for (Link tailUserLink : allLinks) {

			Node sector = tailUserLink.getSector();

			String hql = "select distinct link from Link link inner join link.value momento where link.headNode = :sector order by momento.tempo";

			Query query = DB.getSession().createQuery(hql);
			query.setParameter("sector", sector);

			List<Link> headUsersLink = query.list();

			for (Link headUserLink : headUsersLink) {
				if (!tailUserLink.equals(headUserLink)) {

					String linkName = "from" + tailUserLink.getUser().getName()
							+ "_to" + headUserLink.getUser().getName();
					String alterName = "from"
							+ headUserLink.getUser().getName() + "_to"
							+ tailUserLink.getUser().getName();

					Link newLink = (Link) DB.getSession().get(Link.class,
							linkName);

					if (newLink == null) {
						newLink = (Link) DB.getSession().get(Link.class,
								alterName);
					}

					if (newLink == null) {
						newLink = new Link(linkName, tailUserLink.getUser(),
								headUserLink.getUser());
						newLink.addCrime(tailUserLink.getValue());
						newLink.addCrime(headUserLink.getValue());
						DB.getSession().save(newLink);
						newLinks.add(newLink);
						// System.out.println(newLink.getTailNode().getName() +
						// "     " + newLink.getHeadNode().getName());
					} else {
						newLink.addCrime(tailUserLink.getValue());
						newLink.addCrime(headUserLink.getValue());
					}
				}
			}
		}

		trans.commit();

		return newLinks;
	}

	@SuppressWarnings("unchecked")
	public static void mainUserGraph() {
		List<Link> allLinks = DB
				.getSession()
				.createQuery(
						"select distinct l from Link l inner join l.value m order by m.tempo")
				.list();
		List<Link> userGraph = createUserGraph(allLinks);
		new Metrics(userGraph).printMetrics();
	}

	public static void mainNodeMetrics() {

		// List<Node> allUsers = DB.getUserNodeList();
		List<Node> allSectors = DB.getSectorNodeList();

		/*
		 * NodeMetrics userMetrics = new NodeMetrics(new
		 * ArrayList<Node>(allUsers)); userMetrics.printCrimesSequence();
		 * userMetrics.printDegreeSequence();
		 */

		CrimeMetrics sectorMetrics = new CrimeMetrics(allSectors);

		// sectorMetrics.printDegreeSequence();

		int[] crimesSequence = sectorMetrics.getCrimesSequence();

		double alpha = CalcUtil.calcAlpha(crimesSequence);
		System.out.println("Alpha: " + alpha);

		double r2 = CalcUtil.calcR2(alpha, crimesSequence);
		System.out.println("R2: " + r2);
	}

	public static void mainSectorGraph() {
		try {
			SectorGraphFactory.create();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {

		mainSectorGraph();
		// mainNodeMetrics();

	}
}
